package com.stephen.jsbridge.utils;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Vibrator;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class Utils {
    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

    public static void showLongHintInfo(Context context, String text){
        Toast.makeText(context, text, Toast.LENGTH_LONG).show();
    }

    public static void showShortHintInfo(Context context, String text){
        Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
    }

    //启动activity并关闭
    public static void startActivityAndFinish(Activity activity, Class<?> cls){
        startActivityAndFinish(activity, cls, null);
    }
    public static void startActivityAndFinish(Activity activity, Class<?> cls, Bundle bundle){
        Intent intent = new Intent(activity,cls);
        if(null != bundle)intent.putExtras(bundle);
        activity.startActivity(intent);
        activity.finish();
        activity.overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);
    }
    //启动activity并关闭且清除顶层
    public static void startActivityAndClearTopFinish(Activity activity, Class<?> cls, Bundle bundle){
        Intent intent = new Intent(activity,cls);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TASK);
        if(null != bundle)intent.putExtras(bundle);
        activity.startActivity(intent);
        activity.finish();
        activity.overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);
    }
    //启动activity不关闭
    public static void startActivityNoFinish(Activity activity, Class<?> cls){
        startActivityNoFinish(activity, cls, null);
    }
    public static void startActivityNoFinish(Activity activity, Class<?> cls, Bundle bundle){
        startActivityNoFinish(activity, cls, bundle, 1);
    }
    public static void startActivityNoFinish(Activity activity, Class<?> cls, Bundle bundle, int requestCode){
        Intent intent = new Intent(activity,cls);
        if(null != bundle)intent.putExtras(bundle);
        activity.startActivityForResult(intent,requestCode);//requestCode不能为0和负数,不然onActivityResult不执行
        activity.overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right);
    }
    //得到应用包的签名信息
    public static String getPackageSignature(Context context, String packageName){
        try{
            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);//通过包管理器获得指定包名包含签名的包信息
            if(null == packageInfo)return null;
            Signature[] signatures = packageInfo.signatures;//通过返回的包信息获得签名数组
            if(null != signatures && signatures.length > 0){
                StringBuilder stringBuilder = new StringBuilder();
                for(Signature signature : signatures){//循环遍历签名数组拼接应用签名
                    stringBuilder.append(signature.toCharsString());
                }//end of for
                return stringBuilder.toString();
            }//end of if
        }catch(PackageManager.NameNotFoundException e){
            e.printStackTrace();
        }
        return null;
    }
    //得到进程名字
    public static String getProcessName(Context cxt, int pid) {
        ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
        if(null == runningApps)return null;
        for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
            if (procInfo.pid == pid)return procInfo.processName;
        }//end of if
        return null;
    }
    //判断程序是否在前台运行(根据activity比较)
    public static boolean isTopRunningProgram(Context context, String MainActivityName) {
        ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasksInfo = mActivityManager.getRunningTasks(1);
        if(null != tasksInfo && tasksInfo.size() > 0) {// 应用程序位于堆栈的顶层
            if (MainActivityName.equals(tasksInfo.get(0).topActivity.getClassName())) {
                return true;
            }//end fo if
        }//end of if
        return false;
    }
    //判断程序是否在前台运行(根据整个主程序比较)
    public static boolean isTopRunningProgram(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        String packageName = context.getPackageName();
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if (null == appProcesses) return false;
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.processName.equals(packageName) && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                return true;
            }//end of if
        }//end of for
        return false;
    }
    //判断一个Service是否运行(serviceName是包名+服务的类名,例如:net.loonggg.testbackstage.TestService)
    public static boolean isServiceWorking(Context context, String serviceName) {
        ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : myManager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceName.equals(service.service.getClassName().toString())){
                return true;
            }
        }
        return false;
    }
    //序列化对象
    public static String serializeObject(Object object){
        try {
            if (null != object) {
                long startTime = System.currentTimeMillis();
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
                objectOutputStream.writeObject(object);
                String serStr = byteArrayOutputStream.toString("ISO-8859-1");
                serStr = java.net.URLEncoder.encode(serStr, "UTF-8");
                objectOutputStream.close();
                byteArrayOutputStream.close();
                //System.out.println("序列化成功,耗时为:"+ (System.currentTimeMillis() - startTime)+"ms");
                return serStr;
            }else{
                System.out.println("序列对象是null,返回null");
                return null;
            }
        } catch (IOException e) {
            System.out.println("序列化异常!");
            e.printStackTrace();
            return null;
        }
    }
    //反序列化对象
    public static Object deSerializationObject(String saveObjStr){
        try {
            if(!TextUtils.isEmpty(saveObjStr) && saveObjStr.length() > 0){
                long startTime = System.currentTimeMillis();
                String redStr = java.net.URLDecoder.decode(saveObjStr, "UTF-8");
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(redStr.getBytes("ISO-8859-1"));
                ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
                Object obj = objectInputStream.readObject();
                objectInputStream.close();
                byteArrayInputStream.close();
                //System.out.println("反序列化成功,耗时为:" + (System.currentTimeMillis() - startTime)+"ms");
                return obj;
            }else{
                System.out.println("反序列对象是null,返回null");
                return null;
            }
        } catch (Exception e) {
            System.out.println("反序列化异常!");
            e.printStackTrace();
            return null;
        }
    }
    //深克隆clone对象或容器
    public static <T> T deepCloneObject(T src){
        try {
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(src);

            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream in =new ObjectInputStream(byteIn);
            T dest = (T) in.readObject();
            //System.out.println("反序列化深克隆对象成功!");
            return dest;
        } catch (Exception e) {
            System.out.println("反序列化深克隆对象异常!");
            e.printStackTrace();
            return null;
        }
    }
    //验证ip是否合法
    public static boolean ipCheck(String ip) {
        if (ip != null && !ip.isEmpty()) {
            String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."// 定义正则表达式
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
            if(ip.matches(regex)) {// 判断ip地址是否与正则表达式匹配
                return true;
            }else{
                return false;
            }
        }
        return false;
    }
    // 判读是否是文件
    public static boolean IsFile(String filePath) {
        File dir = new File(filePath);
        if (dir.isFile())return true;
        return false;
    }
    //判读目录是否存在，不存在创建
    public static void ViewOrCreateDir(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists())dir.mkdirs();
    }
    //判读文件是否存在，存在删除
    public static boolean ViewAndDeleteDirOrFile(String filePath) {
        if(!TextUtils.isEmpty(filePath)) {
            File dir = new File(filePath);
            if(dir.exists())return dir.delete();
        }//end of if
        return false;
    }
    public static boolean isHaveSDCard(){
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))return true;
        return false;
    }
    public static String getSD_CardRootPath(){
        if (isHaveSDCard())return Environment.getExternalStorageDirectory().getAbsolutePath();
        return null;
    }
    public static boolean isFileExits(String file){
        if((new File(file)).exists())return true;
        return false;
    }
    public static int dp2px(Context context, int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,context.getResources().getDisplayMetrics());
    }
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
    //得到屏幕密度
    public static float getScreenDensity(Context context) {
        return context.getResources().getDisplayMetrics().density;
    }
    //获取当前版本标示号
    public static int getCurrentVersionCode(Context mContext){
        try {
            return mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    //获取当前版本号
    public static String getCurrentVersionName(Context mContext){
        try {
            return mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    //重新计算ListView或GridView高度
    public static int reSetListViewHeightBasedOnChildren(AbsListView absListView) {
        int totalHeight = 0;
        ListAdapter listAdapter = absListView.getAdapter();
        if (null == listAdapter) {
            return 0;
        }//end of if
        for (int i = 0, len = listAdapter.getCount(); i < len; i++) {
            View listItem = listAdapter.getView(i, null, absListView);
            listItem.measure(0, 0);//计算子项View的宽高
            totalHeight += listItem.getMeasuredHeight();//统计所有子项的总高度
        }//end of for
        if(absListView instanceof ListView){
            totalHeight += (((ListView)absListView).getDividerHeight() * (listAdapter.getCount() - 1));
        }//end of if
        ViewGroup.LayoutParams params = absListView.getLayoutParams();
        if(null != params){
            params.height = totalHeight;// listView.getDividerHeight()获取子项间分隔符占用的高度
            absListView.setLayoutParams(params);
        }//end of if
        return totalHeight;
    }
    public static Point getViewWidthAndHeight(View view){
        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        return (new Point(view.getMeasuredWidth(),view.getMeasuredHeight()));
    }
    //安装apk方法
    public static void installApk(Context context, String filename) {
        File file = new File(filename);
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
        context.startActivity(intent);
    }
    //检查生成被10整除整数
    public static int checkCreateDivisionInteger(int checkValue){
        if(0 != checkValue){
            int val = checkValue % 10;
            if(0 != val){
                if(val < 5){
                    checkValue -= val;
                }else{
                    checkValue += (10 - val);
                }
            }//end of if
        }//end of if
        return checkValue;
    }
    /*计算md5码start*/
    public static String getMD5Str(String str) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            if(!TextUtils.isEmpty(str))messageDigest.update(str.getBytes("UTF-8"));
            byte[] byteArray = messageDigest.digest();
            StringBuffer md5StrBuff = new StringBuffer();
            for (int i = 0; i < byteArray.length; i++) {
                if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
                    md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
                else
                    md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
            }
            return md5StrBuff.toString();
        }catch(Exception e) {
            return null;
        }
    }
    public static String getStringMD5(String s) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f' };
        try {
            byte[] strTemp = s.getBytes();
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte b = md[i];
                str[k++] = hexDigits[b >> 4 & 0xf];
                str[k++] = hexDigits[b & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }
    public static String getFileMD5(File file) {
        if (!IsFile(file.getAbsolutePath())) {
            return null;
        }
        MessageDigest digest = null;
        FileInputStream in = null;
        byte buffer[] = new byte[1024];
        int len;
        try {
            digest = MessageDigest.getInstance("MD5");
            in = new FileInputStream(file);
            while ((len = in.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        BigInteger bigInt = new BigInteger(1, digest.digest());
        return bigInt.toString(16);
    }
    public static Map<String,String> getDirMD5(File file, boolean listChild) {
        if (!file.isDirectory()) {
            return null;
        }
        Map<String, String> map = new HashMap<String, String>();
        String md5;
        File files[] = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            File f = files[i];
            if (f.isDirectory() && listChild) {
                map.putAll(getDirMD5(f, listChild));
            } else {
                md5 = getFileMD5(f);
                if (md5 != null) {
                    map.put(f.getPath(), md5);
                }
            }
        }
        return map;
    }
	/*计算md5码end*/

    //拷贝asset文件,返回组装好的文件完整路径
    public static File copyAssetFile(Context context, String assetFilePath, String assetFileName, File outDir)throws Exception {
        File outFile = new File(outDir,assetFileName);
        if(outFile.exists())outFile.delete();
        if(!outFile.getParentFile().exists())outFile.getParentFile().mkdirs();
        InputStream is;
        if(TextUtils.isEmpty(assetFilePath)){
            is = context.getAssets().open(assetFileName);
        }else{
            is = context.getAssets().open(assetFilePath+ File.separator+assetFileName);
        }
        FileOutputStream out = new FileOutputStream(outFile);
        byte buf[] = new byte[1024];
        int len;
        while((len = is.read(buf)) > 0){
            out.write(buf, 0, len);
        }//end of while
        out.close();
        is.close();
        return outFile;
    }
    //判断是否需要隐藏键盘
    public static boolean isShouldHideKeyboard(View view, MotionEvent event) {
        if(null != view && (view instanceof EditText)){
            int[] location = {0, 0};
            view.getLocationInWindow(location);
            int left = location[0],top = location[1],bottom = top + view.getHeight(),right = left + view.getWidth();
            if(event.getX() > left && event.getX() < right && event.getY() > top && event.getY() < bottom){
                return false;
            }else{
                return true;
            }
        }//end of if
        return false;
    }

    //获取activity中的根布局
    public static View getRootViewForActivity(Activity activity) {
        try{
            return ((ViewGroup)activity.getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0);
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }

    //获取视图中根布局并转换成ViewGroup
    public static ViewGroup convertRootViewToViewGroup(View mainView){
        if(null != mainView.getRootView() && mainView.getRootView() instanceof ViewGroup){
            return (ViewGroup)mainView.getRootView();//ViewGroup subclass AbsoluteLayout, AdapterView, FrameLayout, LinearLayout, RelativeLayout, SlidingDrawer
        }//end of if
        return null;
    }

    //得到子控件在父布局中的索引
    public static int getChildViewInRootViewIndex(ViewGroup rootView, View mainView, int findViewId){
        if(null == rootView)rootView = convertRootViewToViewGroup(mainView);
        if(null != rootView){
            for(int i = 0;i < rootView.getChildCount();i++){
                View childView = rootView.getChildAt(i);
                if(null != childView && findViewId == childView.getId())return i;
            }//end of for
        }//end of if
        return -1;
    }

    //设置TextView环绕图片(direction value is 1/left,2/top,3/right,4/bottom)
    public static void setTextViewAroundDrawable(Context context, TextView textView, int imgResId, int imgWidthDp, int imgHeightDp, int imgPaddingDp, int direction) {
        setTextViewAroundDrawable(context,textView,context.getResources().getDrawable(imgResId),imgWidthDp,imgHeightDp,imgPaddingDp,direction);
    }
    public static void setTextViewAroundDrawable(Context context, TextView textView, Drawable aroundDrawable, int imgWidthDp, int imgHeightDp, int imgPaddingDp, int direction){
        if(null != textView && null != aroundDrawable){
            aroundDrawable.setBounds(0,0, dp2px(context,imgWidthDp),dp2px(context,imgHeightDp));
            textView.setCompoundDrawablePadding(dp2px(context,imgPaddingDp));
            switch(direction){
                case Gravity.LEFT:
                    textView.setCompoundDrawables(aroundDrawable, null, null, null);
                    break;
                case Gravity.TOP:
                    textView.setCompoundDrawables(null, aroundDrawable, null, null);
                    break;
                case Gravity.RIGHT:
                    textView.setCompoundDrawables(null, null, aroundDrawable, null);
                    break;
                case Gravity.BOTTOM:
                    textView.setCompoundDrawables(null, null, null, aroundDrawable);
                    break;
            }//end of switch
        }//edn of if
    }
    //产生一个不重复的id
    public static int generateViewId() {
        for(;;){
            final int result = sNextGeneratedId.get();
            int newValue = result + 1;
            if (newValue > 0x00FFFFFF) newValue = 1;//Roll over to 1, not 0.
            if(sNextGeneratedId.compareAndSet(result, newValue))return result;
        }//end of for
    }
    public static void setBackgroundAllVersion(View view, Drawable bgDrawable){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
            view.setBackground(bgDrawable);
        }else{
            view.setBackgroundDrawable(bgDrawable);
        }
    }
}
